import * as THREE from "three";
import Loader from "@/three/Loader.js";
import configResources from "@/assets/resources.js";
import MatCap from "@/materials/matcap.js";
import groundShadow from "@/materials/groundShadow.js";
import RailCar from "@/three/RailCar.js";
import Windmill from "@/three/WindMill.js";
import Carousel from "@/three/Carousel.js";
import Ship from "@/three/Ship.js";
import DropRotation from "@/three/DropRotation.js";
import DropUp from "@/three/DropUp.js";
import Ferris from "@/three/Ferris.js";
import CoffeeSmoke from "@/three/CoffeeSmoke.js";
import Physics from "@/three/Physics.js";
import CannonDebugger from "cannon-es-debugger";
import Repeats from "@/three/Repeats.js";
import Shields from "@/three/Shields.js";
import { SHAPE_TYPES } from "cannon-es";
import Car from "@/three/Car.js";
import Bricks from "@/three/Bricks.js";
import Trees from "@/three/Trees.js";

export default class World {
  constructor(config) {
    this.config = config;
    this.railCar = new RailCar();
    this.windMill = new Windmill();
    this.carousel = new Carousel();
    this.ship = new Ship();
    this.dropRotation = new DropRotation();
    this.dropUp = new DropUp();
    this.ferris = new Ferris();
    this.coffeeSmoke = new CoffeeSmoke();

    this.physics = new Physics();
    this.repeats = new Repeats(this.physics);
    this.shields = new Shields(this.physics);
    this.car = new Car(this.physics);
    this.bricks = new Bricks(this.physics);
    this.trees = new Trees(this.physics);

    this.cannonDebugger = CannonDebugger(this.config.scene, this.physics.world);
    this.loader = new Loader();
    this.loader.load(configResources);
    this.load();
  }

  build(resources) {
    const modelPlayground = resources["model-playground"].scene;
    const modelCarScene = resources["model-car"].scene;
    const dataRailPoints = resources["data-rail-points"];
    this.railCar.addPathLine(dataRailPoints);

    modelPlayground.traverse((child) => {
      if (child.isMesh) {
        child.material.depthWrite = false;
        child.material.blending =  THREE.AdditiveBlending;
      }
    });
    modelCarScene.traverse((child) => {
      if (child.isMesh) {
        child.material.depthWrite = false;
        child.material.blending =  THREE.NoBlending;
      }
    })

    const models = [...modelPlayground.children, ...modelCarScene.children];
    models.map((model) => {
      const data = model.userData;
      if (data.matcap) {
        model.material = MatCap(resources[`matcap-${data.matcap}`]);
      }
      if (data["shadow-color"]) {
        model.material.shadowColor = groundShadow(resources["texture-shadow"], data["shadow-color"]);
      }
      if (data.name === "rail-car") {
        this.railCar.add(model);
      }
      if (data.name === "windmill") {
        this.windMill.add(model);
      }
      if (data.name === "carousel-rotation") {
        this.carousel.add(model);
      }
      if (data.name.includes("ship")) {
        this.ship.add(model);
      }
      if (data.name.includes("drop-rotation")) {
        this.dropRotation.add(model);
      }
      if (data.name.includes("drop-up-seat")) {
        this.dropUp.add(model);
      }
      if (data.name.includes("ferris")) {
        this.ferris.add(model);
      }
      if (data.name === "coffee-smoke") {
        this.coffeeSmoke.add(model);
      }
      if (this.repeats.contains(data.name)) {
        this.repeats.add(data.name, model);
      }
      if (data.physics === "static") {
        this.physics.createBody({ mesh: model, mass: 0, shapeType: SHAPE_TYPES.BOX });
      }
      this.bricks.add(resources);
      if (data.name.includes("tree-")) {
        this.trees.add(model);
      }
      if (data.name.includes("area-")) {
        this.shields.add(model);
      }

    });
    this.config.scene.add(modelPlayground);

    this.railCar.build();
    this.config.scene.add(this.railCar.main);

    this.carousel.build();
    this.config.scene.add(this.carousel.main);

    this.ship.build();
    this.config.scene.add(this.ship.main);

    this.dropRotation.build();
    this.config.scene.add(this.dropRotation.main);

    this.dropUp.build();
    this.config.scene.add(this.dropUp.main);

    this.ferris.build();
    this.config.scene.add(this.ferris.main);

    this.repeats.build();
    this.config.scene.add(this.repeats.main);

    this.config.scene.add(this.shields.main);

    this.car.build(modelCarScene);
    this.config.scene.add(this.car.main);
    this.isReady = true;

    this.bricks.build();
    this.config.scene.add(this.bricks.main);

    this.trees.build();
    this.config.scene.add(this.trees.main);
  }

  load() {
    this.loader.onFileLoaded(() => {
      const value = this.loader.totalSuccess / this.loader.total * 100;
    });

    this.loader.onLoadEnd((resources) => {
      this.build(resources);
    });
  }


}